package at.ac.tuwien.dse.health.entity;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

/**
 * Date when a surgery is scheduled.
 *
 * @author Bernhard Nickel
 * @author Gregor Schauer
 * @author Dominik Strasser
 */
@Entity
@NamedQueries({
		@NamedQuery(name = SurgerySlot.GET_SLOTS_FOR_DOCTOR, query = "SELECT s FROM SurgerySlot s WHERE s.doctor=:filterObject AND startDate > NOW() ORDER BY startDate"),
		@NamedQuery(name = SurgerySlot.GET_SLOTS_FOR_PATIENT, query = "SELECT s FROM SurgerySlot s WHERE s.patient=:filterObject AND startDate > NOW() ORDER BY startDate"),
		@NamedQuery(name = SurgerySlot.GET_SLOTS_FOR_HOSPITAL, query = "SELECT s FROM SurgerySlot s WHERE s.hospital=:filterObject AND startDate > NOW() ORDER BY startDate"),
		@NamedQuery(name = SurgerySlot.GET_EMPTY_SLOTS, query = "SELECT s FROM SurgerySlot s WHERE hospital.name=:filterObject AND doctor IS NULL AND patient IS NULL AND startDate > NOW() ORDER BY startDate")
})
public class SurgerySlot implements Serializable {
	public static final String GET_SLOTS_FOR_PATIENT = "SurgerySlot#getSlotsForPatient";
	public static final String GET_SLOTS_FOR_DOCTOR = "SurgerySlot#getSlotsForDoctor";
	public static final String GET_SLOTS_FOR_HOSPITAL = "SurgerySlot#getSlotsForHospital";
	public static final String GET_EMPTY_SLOTS = "SurgerySlot#getEmptySlots";
	private Long id;
	private Date startDate;
	private Date endDate;
	private Doctor doctor;
	private Patient patient;
	private Hospital hospital;
	private Department department;

	@Id
	@GeneratedValue
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Basic(optional = false)
	public Date getStartDate() {
		return startDate;
	}

	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	@Basic(optional = false)
	public Date getEndDate() {
		return endDate;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	@ManyToOne
	public Doctor getDoctor() {
		return doctor;
	}

	public void setDoctor(Doctor doctor) {
		this.doctor = doctor;
	}

	@ManyToOne
	public Patient getPatient() {
		return patient;
	}

	public void setPatient(Patient patient) {
		this.patient = patient;
	}

	@ManyToOne(optional = false)
	public Hospital getHospital() {
		return hospital;
	}

	public void setHospital(Hospital hospital) {
		this.hospital = hospital;
	}

	@ManyToOne
	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

	@Override
	public String toString() {
		return startDate + " - " + endDate;
	}

	/**
	 * Returns whether this {@link SurgerySlot} is free or reserved.
	 * <p/>
	 * A slot is free if both {@code doctor} and {@code patient} is {@code null}.
	 *
	 * @return {@code true} if the slot is free, {@code false} otherwise
	 */
	@Transient
	public boolean isFree() {
		return getDoctor() == null && getPatient() == null;
	}
}
